local Industry = require "industry._base"
local _farm = {}

-- 常量定义
local leaf = 1073913964       -- 粽叶
local paddy = 1073909779      -- 水稻
local sugar_cane = 1073918073 -- 甘蔗
local jujube = 1073934366     -- 红枣

---@enum CropType
local CROP = {
    REED = "芦苇",
    RICE = "水稻",
    SUGARCANE = "甘蔗",
    JUJUBE = "枣树"
}

---@class CropData
---@field name CropType 作物类型
---@field item integer 对应物品ID
---@field level integer 当前等级
---@field growth_timers integer[] 生长计时器数组
---@field units_grow Unit[] 生长阶段单位
---@field units_ripe Unit[] 成熟阶段单位
---@field levelup_unit Unit 升级单位
---@field info_unit Unit 信息显示单位
---@field max_growth_time integer 最大生长时间
---@field max_double_odds integer 最大双倍概率

---@class farmMeta
---@field 芦苇 integer[] 芦苇产业数据
---@field 水稻 integer[] 水稻产业数据
---@field 甘蔗 integer[] 甘蔗产业数据
---@field 枣树 integer[] 枣树产业数据

---@class Farm : Industry
---@field crops table<CropType, CropData> 作物数据表
---@field growthGeneration integer 生长计时器ID
---@field metadata farmMeta 元数据
---@field rootdata storeMeta 根数据
_farm.Farm = {}
_farm.Farm.__index = _farm.Farm
setmetatable(_farm.Farm, { __index = Industry })

-- 位置常量
local ORIGIN_POSITION = math.Vector3(1000.0, 1000.0, 1000.0)
local GROWTH_POSITION = math.Vector3(1000.0, 1000.0, 1000.0)
local MAX_SLOTS = 6

---构造新的农场实例
---@param _role Role 农场管理员
---@return Farm
function _farm.Farm:new(_role)
    local parent = Industry:new(_role)
    local instance = setmetatable(parent, self) --[[@as Farm]]

    -- 初始化作物数据
    instance.crops = {
        [CROP.REED] = {
            name = CROP.REED,
            item = leaf,
            level = 1,
            growth_timers = { 60, 60, 60, 60, 60, 60 },
            max_growth_time = 60,
            max_double_odds = 0,
            units_grow = {},
            units_ripe = {},
            levelup_unit = nil,
            info_unit = nil
        },
        [CROP.RICE] = {
            name = CROP.RICE,
            item = paddy,
            level = 1,
            growth_timers = { 60, 60, 60, 60, 60, 60 },
            max_growth_time = 60,
            max_double_odds = 0,
            units_grow = {},
            units_ripe = {},
            levelup_unit = nil,
            info_unit = nil
        },
        [CROP.SUGARCANE] = {
            name = CROP.SUGARCANE,
            item = sugar_cane,
            level = 1,
            growth_timers = { 60, 60, 60, 60, 60, 60 },
            max_growth_time = 60,
            max_double_odds = 0,
            units_grow = {},
            units_ripe = {},
            levelup_unit = nil,
            info_unit = nil
        },
        [CROP.JUJUBE] = {
            name = CROP.JUJUBE,
            item = jujube,
            level = 1,
            growth_timers = { 60, 60, 60, 60, 60, 60 },
            max_growth_time = 60,
            max_double_odds = 0,
            units_grow = {},
            units_ripe = {},
            levelup_unit = nil,
            info_unit = nil
        }
    }

    instance:bind(_role.get_kv_by_type(Enums.ValueType.Int, "编号"))
    return instance
end

---绑定农场场景
---@param order integer 农场编号
function _farm.Farm:bind(order)
    for crop_type, crop in pairs(self.crops) do
        local display_name = ("%s信息%d"):format(crop_type, order)
        local group_name = ("%s%d"):format(crop_type, order)
        local levelup_name = ("%s升级%d"):format(crop_type, order)

        -- 绑定升级单位
        crop.levelup_unit = GameAPI.get_unit(GameAPI.get_unit_id_by_name(levelup_name))
        crop.levelup_unit.set_kv_by_type(Enums.ValueType.Role, "主人", self.owner)

        -- 绑定信息单位
        crop.info_unit = GameAPI.get_unit(GameAPI.get_unit_id_by_name(display_name))

        -- 绑定作物单位组
        local group = GameAPI.get_unit(GameAPI.get_unit_id_by_name(group_name))
        crop.units_grow = {}
        crop.units_ripe = {}

        for i = 1, MAX_SLOTS do
            -- 生长阶段单位
            local grow_unit = group.get_child_by_name(("生长%d"):format(i))
            print(group, ("生长%d"):format(i))
            table.insert(crop.units_grow, grow_unit)
            grow_unit.set_kv_by_type(Enums.ValueType.Vector3, "原始位置", grow_unit.get_position())
            grow_unit.set_kv_by_type(Enums.ValueType.Int, "编号", i)
            grow_unit.set_kv_by_type(Enums.ValueType.Role, "主人", self.owner)

            -- 成熟阶段单位
            local ripe_unit = group.get_child_by_name(("成熟%d"):format(i))
            table.insert(crop.units_ripe, ripe_unit)
            ripe_unit.set_kv_by_type(Enums.ValueType.Vector3, "原始位置", ripe_unit.get_position())
            ripe_unit.set_position(ORIGIN_POSITION)
            ripe_unit.set_model_visible(false)
            ripe_unit.set_kv_by_type(Enums.ValueType.Int, "编号", i)
            ripe_unit.set_kv_by_type(Enums.ValueType.Role, "主人", self.owner)
        end
    end
end

---开始农场运作
function _farm.Farm:start()
    self:update_info()
    self:start_growth()
end

---停止农场运作
function _farm.Farm:stop()
    self:stop_growth()
    self:save_data()
end

---开始生长计时
function _farm.Farm:start_growth()
    self.growthGeneration = LuaAPI.global_register_trigger_event({ EVENT.REPEAT_TIMEOUT, 1 }, function()
        for _, crop in pairs(self.crops) do
            for i, timer in ipairs(crop.growth_timers) do
                if timer > 0 then
                    crop.growth_timers[i] = timer - 1
                    if timer == 1 then
                        self:ripe(crop.name, i)
                    end
                end
            end
        end
    end)
end

---停止生长计时
function _farm.Farm:stop_growth()
    if self.growthGeneration ~= -1 then
        LuaAPI.global_unregister_trigger_event(self.growthGeneration)
        self.growthGeneration = -1
    end
end

---设置元数据
---@param metadata farmMeta
function _farm.Farm:set_metadata(metadata)
    Industry.set_metadata(self, metadata)

    for crop_type, crop in pairs(self.crops) do
        local data = metadata[crop_type]
        if data then
            crop.level = data[1]
            for i = 1, MAX_SLOTS do
                crop.growth_timers[i] = data[i + 1]
                if data[i + 1] == 0 then
                    self:ripe(crop_type, i)
                end
            end
            self:update_crop_stats(crop)
        end
    end
end

---保存数据
function _farm.Farm:save_data()
    for crop_type, crop in pairs(self.crops) do
        local data = { crop.level }
        for i = 1, MAX_SLOTS do
            data[i + 1] = crop.growth_timers[i]
        end
        self.metadata[crop_type] = data
    end
end

---更新作物状态
---@param crop CropData 作物数据
function _farm.Farm:update_crop_stats(crop)
    if crop.level <= 10 then
        crop.max_growth_time = 60 - (crop.level - 1) * 3
        crop.max_double_odds = 0
    else
        crop.max_growth_time = 30 - crop.level + 10
        crop.max_double_odds = (crop.level - 10) * 10
    end
end

---更新信息板
function _farm.Farm:update_info()
    for _, crop in pairs(self.crops) do
        crop.info_unit.set_billboard_content(("%s\n%d"):format(crop.name, crop.level))
    end
end

---作物成熟处理
---@param crop_type CropType 作物类型
---@param slot integer 位置编号
function _farm.Farm:ripe(crop_type, slot)
    local crop = self.crops[crop_type]
    if not crop then return end

    local grow_unit = crop.units_grow[slot]
    local ripe_unit = crop.units_ripe[slot]

    if grow_unit and ripe_unit then
        ripe_unit.set_position(ripe_unit.get_kv_by_type(Enums.ValueType.Vector3, "原始位置"))
        ripe_unit.set_model_visible(true)
        grow_unit.set_position(GROWTH_POSITION)
        grow_unit.set_model_visible(false)
    end
end

---收割作物
---@param user Role 收割者
---@param crop_type CropType 作物类型
---@param slot integer 位置编号
function _farm.Farm:harvest(user, crop_type, slot)
    local crop = self.crops[crop_type]
    if not crop or not self:could_harvest(crop_type, slot) then return end

    local grow_unit = crop.units_grow[slot]
    local ripe_unit = crop.units_ripe[slot]

    -- 给予收获物品
    user.get_ctrl_unit().create_equipment_to_slot(crop.item, 2)

    -- 双倍收获判定
    if GameAPI.random_int(0, 100) <= crop.max_double_odds then
        user.get_ctrl_unit().create_equipment_to_slot(crop.item, 2)
        user.show_tips("成功双倍收获！", 1.0)
    end

    -- 重置作物状态
    crop.growth_timers[slot] = crop.max_growth_time
    ripe_unit.set_position(ORIGIN_POSITION)
    ripe_unit.set_model_visible(false)
    grow_unit.set_position(grow_unit.get_kv_by_type(Enums.ValueType.Vector3, "原始位置"))
    grow_unit.set_model_visible(true)
end

---检查是否可以收割
---@param crop_type CropType 作物类型
---@param slot integer 位置编号
---@return boolean
function _farm.Farm:could_harvest(crop_type, slot)
    local crop = self.crops[crop_type]
    return crop and crop.growth_timers[slot] == 0
end

---获取指定位置信息
---@param crop_type CropType 作物类型
---@param slot integer 位置编号
---@return string
function _farm.Farm:get_spec_info(crop_type, slot)
    local crop = self.crops[crop_type]
    if not crop then return "" end

    local timer = crop.growth_timers[slot]
    return timer == 0 and "可收获" or ("成长中，剩余 #c00ff00%d #cffffff秒"):format(timer)
end

---获取产业信息
---@param crop_type CropType 作物类型
---@return string
function _farm.Farm:get_info(crop_type)
    local crop = self.crops[crop_type]
    if not crop then return "" end

    local levelup_money = self:get_levelup_money(crop_type)
    local assets = self.rootdata.assets
    local cost_status = assets >= levelup_money and
        ("可升级(花费 #cffff00%d #cffffff金币)"):format(levelup_money) or
        ("还差 #cffff00%d #cffffff金币升级"):format(levelup_money - assets)

    return ("%s\n本次升级：%s"):format(cost_status, self:get_levelup_tip(crop_type))
end

---获取升级所需金币
---@param crop_type CropType 作物类型
---@return integer
function _farm.Farm:get_levelup_money(crop_type)
    local crop = self.crops[crop_type]
    if not crop then return -1 end

    if crop.level <= 10 then
        return 120 * (crop.level - 1) + 100
    else
        return 175 * crop.level
    end
end

---获取升级提示
---@param crop_type CropType 作物类型
---@return string
function _farm.Farm:get_levelup_tip(crop_type)
    local crop = self.crops[crop_type]
    if not crop then return "" end

    local next_level = crop.level + 1
    if next_level <= 10 then
        return ("作物成长时间 #c00ff00%d → %d"):format(
            crop.max_growth_time,
            60 - (crop.level) * 3
        )
    elseif next_level <= 20 then
        return ("作物成长时间 #c00ff00%d → %d#cffffff，双倍收获概率 #c00ff00%d%% → %d%%"):format(
            crop.max_growth_time,
            30 - next_level + 10,
            crop.max_double_odds,
            (next_level - 10) * 10
        )
    else
        return "已满级"
    end
end

---设置作物等级
---@param level integer 新等级
---@param crop_type CropType 作物类型
function _farm.Farm:set_level(level, crop_type)
    local crop = self.crops[crop_type]
    if crop then
        crop.level = level
        self:update_crop_stats(crop)
    end
end

---升级作物
---@param crop_type CropType 作物类型
function _farm.Farm:levelup(crop_type)
    self:set_level(self.crops[crop_type].level + 1, crop_type)
end

return _farm
